package jdos.dos;

import jdos.Dosbox;
import jdos.cpu.CPU_Regs;
import jdos.hardware.*;
import jdos.ints.Bios_disk;
import jdos.misc.Program;
import jdos.util.*;


public class Dos_programs {

	static public class RebootException extends RuntimeException {
	}

	public static void BOOT(char drive) {

        /* In secure mode don't allow people to boot stuff.
         * They might try to corrupt the data on it */

        int i=0;

        int eip = 0x7c00;
        byte[] bootarea = new byte[512];

        Bios_disk.imageDiskList[drive-65].Read_Sector(0,0,1,bootarea);

        if ((bootarea[0]==0x50) && (bootarea[1]==0x43) && (bootarea[2]==0x6a) && (bootarea[3]==0x72)) {
        	//del
        } else {
            Program.DosPrint("Booting from drive %c...\r\n", new Object[] {new Character(drive)});

            /* revector some dos-allocated interrupts */
            Memory.real_writed(0,0x01*4,0xf000ff53);
            Memory.real_writed(0,0x03*4,0xf000ff53);

            for(i=0;i<bootarea.length;i++) Memory.real_writeb(0, eip + i, bootarea[i]);

            CPU_Regs.SegSet16CS(0);
            CPU_Regs.reg_eip = eip;
            CPU_Regs.SegSet16DS(0);
            CPU_Regs.SegSet16ES(0);
            /* set up stack at a safe place */
            CPU_Regs.SegSet16SS(0x7000);
            CPU_Regs.reg_esp.dword=0x100;
            CPU_Regs.reg_esi.dword=0;
            CPU_Regs.reg_ecx.dword=1;
            CPU_Regs.reg_ebp.dword=0;
            CPU_Regs.reg_eax.dword=0;
            CPU_Regs.reg_edx.dword=0;

            /*
            if (cdrom!=null) {
                CPU_Regs.reg_eax.word(0xAA55);
            }
            */
            if (drive>='C')
                CPU_Regs.reg_edx.low(0x80+drive-'C');
            else
                CPU_Regs.reg_edx.low(drive-'A');
//            Core_dynamic.CPU_Core_Dynamic_Cache_Init(true);
//            CPU.cpudecoder= Core_dynamic.CPU_Core_Dynamic_Run;
//            DecodeBlock.start = 1;

            CPU_Regs.reg_ebx.dword=0x7c00; //Real code probably uses bx to load the image
            

            Dosbox.DOSBOX_RunMachine();
        }
	}

	public static void IMGMOUNT(char drive, /*Bit32u*/long setHeads, /*Bit32u*/long setCyl, /*Bit32u*/long setSect, String path,String type) {
		Bios_disk.imageDisk newImage = null;
		/*Bit32u*/long imagesize;
		BooleanRef ide_slave = new BooleanRef(false);
		IntRef ide_index = new IntRef(-1);
		String ideattach = "auto";
		String fstype = "none";


		if (ideattach.equals("auto")) {
			System.out.println("IDE: index " + ide_index.value + " slave=" + ide_slave.value);
		} else if (!ideattach.equals("none") && ideattach.length() > 0 && Character.isDigit(ideattach.charAt(0))) {
			ide_index.value = ideattach.charAt(0) - '1';
			if (ideattach.length() > 1 && ideattach.charAt(1) == 's') ide_slave.value = true;
			System.out.println("IDE: index " + ide_index.value + " slave=" + ide_slave.value);
		}

		FileIO newDisk = null;
		try {
			newDisk = FileIOFactory.open(path, FileIOFactory.MODE_READ | FileIOFactory.MODE_WRITE);
			imagesize = (newDisk.length() / 1024);
		} catch (Exception e) {
			e.printStackTrace();
			return;
		}
		newImage = new Bios_disk.imageDisk(newDisk, path, imagesize, (imagesize > 2880));
		
		if (imagesize > 2880) newImage.Set_Geometry(setHeads, setCyl, setSect);

		//if(Bios_disk.imageDiskList[drive-'0'] != null) delete imageDiskList[drive-'0'];
		Bios_disk.imageDiskList[drive - '0'] = newImage;
		Bios_disk.updateDPT();
		Program.DosPrint("Drive number %d mounted as %s\r\n", new Object[] { new Integer(drive - '0'), path });
		// If instructed, attach to IDE controller as ATA hard disk
//		if (ide_index.value >= 0 && drive >= '2') {
//			IDE.IDE_Attach(false, ide_index.value, ide_slave.value, newImage.diskimg, (int) newImage.cylinders, (int) newImage.heads, (int) newImage.sectors);
//		}
//		if (drive == 48) Floppy.Attach(0, Bios_disk.imageDiskList[0].diskimg);
//		else if (drive == 49) Floppy.Attach(1, Bios_disk.imageDiskList[1].diskimg);

	}
}
